from django import forms
from django.forms.util import flatatt
from django.template import loader
from django.utils.datastructures import SortedDict
from django.utils.http import int_to_base36
from django.utils.translation import ugettext, ugettext_lazy as _
from django.contrib.auth.models import User, Group
from django.contrib.auth import authenticate, get_user_model
from usuarios.models import Usuario
from universidades.models import Universidad
from django.contrib.auth.tokens import default_token_generator
from django.contrib.sites.models import get_current_site
from django.contrib.auth.hashers import (
     UNUSABLE_PASSWORD, identify_hasher,
)

MAXIMUM_PASSWORD_LENGTH = 4096


class RegistroForm(forms.Form):
    PAIS_CHOICES = [('', '-- Elija un Pais --'), ] + [(p.pais, p.pais) for p in Universidad.objects.all()]
    UNIV_CHOICES = [(u.id, u.nombre) for u in Universidad.objects.all()]
    UNIV_CHOICES.insert(0, ('', '-- Primero elija un Pais --'))

    nombre = forms.CharField()
    apellido = forms.CharField()
    email = forms.EmailField()
    password = forms.CharField()
    confirmacion = forms.CharField()
    #universidad = forms.CharField()
    pais = forms.ChoiceField(choices=PAIS_CHOICES, widget=forms.Select(attrs={'onchange':'get_nombre_universidad();'}))
    universidad = forms.ChoiceField(choices=UNIV_CHOICES)

    def save(self):
        data = self.cleaned_data
        grupo_Identificado = Group.objects.get(name = "Identificado")

        user = User()
        user.first_name = data['nombre']
        user.last_name = data['apellido']
        user.email = data['email']
        user.username = user.email
        user.set_password(data['password'])
        user.save()
        user_group = User.objects.get(email = user.email)
        grupo_Identificado.user_set.add(user_group)
        universidad = Universidad.objects.get(pk=data['universidad'])
        usuario = Usuario(user=user, universidad=universidad)

        usuario.save()

    def is_valid(self):
        valid = super(RegistroForm, self).is_valid()
        data = self.cleaned_data

        if not valid:
            return valid

        if data['password'] != data['confirmacion']:
            return False

        if User.objects.filter(username = data['email']).exists():
            return False

        return True

class EditarForm(forms.Form):
    nombre = forms.CharField()
    apellido = forms.CharField()
    email= forms.EmailField()
    password = forms.CharField(required=False)
    pk_user = forms.IntegerField()
    password_nuevo= forms.CharField(required=False)
    confirmacion= forms.CharField(required=False)

    def save(self):
        data = self.cleaned_data
        user = User.objects.get(pk=data['pk_user'])

        user.first_name = data['nombre']
        user.last_name = data['apellido']
        user.email=data['email']
        user.username=data['email']
        if data['password'] != '':
            user.set_password(data['password_nuevo'])

        user.save()

    
    def is_valid(self):
        valid = super(EditarForm, self).is_valid()
        data = self.cleaned_data

        if not valid:
            return False
        try:
            useraux=User.objects.get(email=data['email'])
            if useraux.pk != data['pk_user']:
                return False
        except:
            pass

        if data['password'] != '':
            user = User.objects.get(pk=data['pk_user'])
            if user.check_password(data['password']):
                if (data['password_nuevo']!='')and(data['password_nuevo'] == data['confirmacion']):
                    return True
                else:
                    return False
            else:
                return False
        else:
            return True


class UnivForm(forms.Form):
    nombre = forms.CharField()
    url = forms.URLField()
    cod_pais=forms.CharField(required=False)
    cod_ciudad=forms.CharField(required=False)
    telefono=forms.CharField(required=False)
    direccion = forms.CharField(required=False)
    pk = forms.IntegerField()
    siglas = forms.CharField(required=False)

    def is_valid(self):
        valid = super(UnivForm, self).is_valid()
        data = self.cleaned_data

        if not valid:
            return False

        return True

    def save(self):
        data = self.cleaned_data
        universidad=Universidad.objects.get(pk=data['pk'])

        universidad.nombre=data['nombre']
        universidad.url=data['url']
        universidad.telefono=data['cod_pais']+'-'+data['cod_ciudad']+'-'+data['telefono']
        universidad.direccion=data['direccion']
        universidad.siglas=data['siglas']

        universidad.save()

class PasswordResetForm(forms.Form):
    error_messages = {
        'unknown': _("That email address doesn't have an associated "
                     "user account. Are you sure you've registered?"),
        'unusable': _("The user account associated with this email "
                      "address cannot reset the password."),
    }
    email = forms.EmailField(label=_("Email"), max_length=254)

    def clean_email(self):
        """
        Validates that an active user exists with the given email address.
        """
        UserModel = get_user_model()
        email = self.cleaned_data["email"]
        self.users_cache = UserModel._default_manager.filter(email__iexact=email)
        if not len(self.users_cache):
            raise forms.ValidationError(self.error_messages['unknown'])
        if not any(user.is_active for user in self.users_cache):
            # none of the filtered users are active
            raise forms.ValidationError(self.error_messages['unknown'])
        if any((user.password == UNUSABLE_PASSWORD)
               for user in self.users_cache):
            raise forms.ValidationError(self.error_messages['unusable'])
        return email

    def save(self, domain_override=None,
             subject_template_name='pass_reset_subject.txt',
             email_template_name='pass_reset_email.html',
             use_https=False, token_generator=default_token_generator,
             from_email=None, request=None):
        """
        Generates a one-use only link for resetting password and sends to the
        user.
        """
        from django.core.mail import send_mail
        for user in self.users_cache:
            if not domain_override:
                current_site = get_current_site(request)
                site_name = current_site.name
                domain = current_site.domain
            else:
                site_name = domain = domain_override
            c = {
                'email': user.email,
                'domain': domain,
                'site_name': site_name,
                'uid': int_to_base36(user.pk),
                'user': user,
                'token': token_generator.make_token(user),
                'protocol': use_https and 'https' or 'http',
            }
            subject = loader.render_to_string(subject_template_name, c)
            # Email subject *must not* contain newlines
            subject = ''.join(subject.splitlines())
            email = loader.render_to_string(email_template_name, c)
            send_mail(subject, email, from_email, [user.email])

class SetPasswordForm(forms.Form):
    """
    A form that lets a user change set his/her password without entering the
    old password
    """
    error_messages = {
        'password_mismatch': _("The two password fields didn't match."),
    }
    new_password1 = forms.CharField(
        label=_("New password"),
        widget=forms.PasswordInput,
        max_length=MAXIMUM_PASSWORD_LENGTH,
    )
    new_password2 = forms.CharField(
        label=_("New password confirmation"),
        widget=forms.PasswordInput,
        max_length=MAXIMUM_PASSWORD_LENGTH,
    )

    def __init__(self, user, *args, **kwargs):
        self.user = user
        super(SetPasswordForm, self).__init__(*args, **kwargs)

    def clean_new_password2(self):
        password1 = self.cleaned_data.get('new_password1')
        password2 = self.cleaned_data.get('new_password2')
        if password1 and password2:
            if password1 != password2:
                raise forms.ValidationError(
                    self.error_messages['password_mismatch'])
        return password2

    def save(self, commit=True):
        self.user.set_password(self.cleaned_data['new_password1'])
        if commit:
            self.user.save()
        return self.user

class PasswordChangeForm(SetPasswordForm):
    """
    A form that lets a user change his/her password by entering
    their old password.
    """
    error_messages = dict(SetPasswordForm.error_messages, **{
        'password_incorrect': _("Your old password was entered incorrectly. "
                                "Please enter it again."),
    })
    old_password = forms.CharField(
        label=_("Old password"),
        widget=forms.PasswordInput,
        max_length=MAXIMUM_PASSWORD_LENGTH,
    )

    def clean_old_password(self):
        """
        Validates that the old_password field is correct.
        """
        old_password = self.cleaned_data["old_password"]
        if not self.user.check_password(old_password):
            raise forms.ValidationError(
                self.error_messages['password_incorrect'])
        return old_password

PasswordChangeForm.base_fields = SortedDict([
    (k, PasswordChangeForm.base_fields[k])
    for k in ['old_password', 'new_password1', 'new_password2']
])